/**
 * (created at 2011-1-28)
 */
package qiushuo.mysqlparser.ast.statement;

import java.sql.SQLSyntaxErrorException;
import java.util.List;

import qiushuo.mysqlparser.ast.expression.Expression;
import qiushuo.mysqlparser.ast.fragment.GroupBy;
import qiushuo.mysqlparser.ast.fragment.Limit;
import qiushuo.mysqlparser.ast.fragment.OrderBy;
import qiushuo.mysqlparser.ast.fragment.tableref.TableReferences;
import qiushuo.mysqlparser.generator.SQLType;
import qiushuo.mysqlparser.util.Pair;

/**
 * @author <a href="mailto:QiuShuo1985@gmail.com">QIU Shuo</a>
 */
public class DMLSelectStatement extends DMLStatement implements Expression {
    public static final int DUP_STRATEGY_UNDEF = 0;
    public static final int DUP_STRATEGY_ALL = 1;
    public static final int DUP_STRATEGY_DISTINCT = 2;
    public static final int DUP_STRATEGY_DISTINCTROW = 3;
    public static final int SQL_CACHE_UNDEF = 0;
    public static final int SQL_CACHE_CACHE = 1;
    public static final int SQL_CACHE_NO_CACHE = 2;
    public static final int LOCK_UNDEF = 0;
    public static final int LOCK_FOR_UPDATE = 1;
    public static final int LOCK_SHARED = 2;
    private final int dupStrategy;
    private final boolean highPriority;
    private final boolean straightJoin;
    private final boolean sqlSmallResult;
    private final boolean sqlBigResult;
    private final boolean sqlBufferResult;
    private final int sqlCache;
    private final boolean sqlCalcFoundRows;
    private final int lockMode;

    /** string: id | `id` | 'id'| _latin1'id' */
    private final List<Pair<Expression, String>> selectExprList;
    private final TableReferences tables;
    private final Expression where;
    private final GroupBy group;
    private final Expression having;
    private final OrderBy order;
    private final Limit limit;

    /**
     * @param opts 1st {@link #dupStrategy}, {@link #sqlCache}
     * @param opts 2nd {@link #highPriority}, {@link #straightJoin},
     *            {@link #sqlSmallResult},{@link #sqlBigResult},
     *            {@link #sqlBufferResult},{@link #sqlCalcFoundRows}
     * @throws SQLSyntaxErrorException
     */
    @SuppressWarnings("unchecked")
    public DMLSelectStatement(Pair<int[], boolean[]> opts, List<Pair<Expression, String>> selectExprList,
                              TableReferences tables, Expression where, GroupBy group, Expression having,
                              OrderBy order, Limit limit, int lockMode) throws SQLSyntaxErrorException {
        int[] opts1 = opts.getFirst();
        this.dupStrategy = opts1[0];
        this.sqlCache = opts1[1];
        boolean[] opts2 = opts.getSecond();
        this.highPriority = opts2[0];
        this.straightJoin = opts2[1];
        this.sqlSmallResult = opts2[2];
        this.sqlBigResult = opts2[3];
        this.sqlBufferResult = opts2[4];
        this.sqlCalcFoundRows = opts2[5];
        if (selectExprList == null) {
            this.selectExprList = null;
        } else if (selectExprList.size() <= 0) {
            throw new SQLSyntaxErrorException("at least one select_expr should be contained in SELECT");
        } else {
            this.selectExprList = ensureListType(selectExprList);
        }
        this.tables = tables;
        this.where = where;
        this.group = group;
        this.having = having;
        this.order = order;
        this.limit = limit;
        this.lockMode = lockMode;
    }

    @Override
    public int getPrecedence() {
        return PRECEDENCE_PRIMARY;
    }

    @Override
    public String generateSql(SQLType type) {
        // QS_TODO gen sql
        throw new UnsupportedOperationException("not implemented yet");
    }

}
